'use strict'

let ChildsManger = require('./manager')
let Child = require('./child')
let globalObject = require('../server/globalobject')
let Transport = require('./transport')
let TcpServer = require('./connector').TcpServer


class RootServer {
  constructor(name) {
    this.name = name //root名字
    this.childsmanager = new ChildsManger() //节点管理器
    this.master = null
    this._remoteCall = {} //注册的远程回调函数
    this.tcpServer = new TcpServer(name)
    this.transports = {}
  }

  createServer(rootport) {
    let self = this
    this.tcpServer.createServer(rootport, function(socket) {
      let transport = new Transport(socket, self)
      self.transports[socket.id] = transport
    })


    //子节点注册到root
    this.rootRemote('register', function(transport, msg, next) {
      let name = msg.name
      console.log(name + ' 子节点注册到 ' + self.name + ' 服务器')
      let child = new Child(name)
      self.childsmanager.addChild(child)
      child.setTransport(transport)
      if (self.master) {
        self._doChildConnect(name)
      }
    })
  }

  //作为root服务器节点，供remote节点调用的接口描述符
  rootRemote(name, cb) {
    this._remoteCall[name] = cb
  }

  getRemoteMothed(msgName) {
    return this._remoteCall[msgName]
  }

  //当node节点连接master时的处理
  _doChildConnect(name) {
    let serverConfig = globalObject.config['servers'][name]
    let remoteport = serverConfig['remoteport']
    if (remoteport) {
      globalObject.remoteMap[name] = remoteport
    }

    //通知有需要连的node节点连接到此root节点
    for (let _name in globalObject.remoteMap) {
      let remoteList = globalObject.remoteMap[_name]
      for (let r in remoteList) {
        if (name === remoteList[r]['rootname']) {
          let msg = {
            rootname: name,
            rootport: remoteList[r]['rootport']
          }
          this.childsmanager.callChild(_name, 'remoteConnect', msg)
          break
        }
      }
    }

    //查看当前是否有可供连接的root节点
    let remoteNodeList = globalObject.remoteMap
    for (let i in remoteport) {
      let rootname = remoteport[i]['rootname']
      if (remoteNodeList[rootname]) {
        let msg = {
          rootname: rootname,
          rootport: remoteport[i]['rootport']
        }
        this.childsmanager.callChild(name, 'remoteConnect', msg)
      }
    }
  }

  _doChildLostConnect(childId) {
    delete globalObject.remote_map[childId]
  }

}

module.exports = RootServer
